package com.sxds.wn.controller;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;

import com.sxds.wn.IConstants;
import com.sxds.wn.security.SecurityService;
import com.sxds.wn.service.IService;
import com.sxds.wn.service.Request;
import com.sxds.wn.service.Response;
import com.sxds.wn.util.StringUtil;

/**
 * Description: <p>抽象实现控制器AbstractController</p>
 * Content Desc:<p>实现AbstractController的控制器可以继承此类<p>
 * Copy Right of Personal Tangtao 2007-2020
 * @author Andy
 * @version 1.0 Create Date:@2008-11-20
 */
public abstract class BaseAbstractController implements Controller,IConstants{


	private Log log = LogFactory.getLog(getClass());
	
	//处理成功后返回的ViewName
	private String successView;
	//错误处理页面的View
	private String failedView;
	//服务接口请求对象
	protected Request andyRequest;
	//服务接口返回对象
	protected Response andyResponse;
	//服务接口
	private IService service;
	//安全认证授权服务接口
	protected SecurityService securityService;
	
	@SuppressWarnings("unchecked")
	public void saveError(HttpServletRequest request, String error) {
		List errors = (List) request.getSession().getAttribute(PAGE_ERRORS_MESSAGES_KEY);
		if (errors == null) {
			errors = new ArrayList();
		}
		errors.add(error);
		request.getSession().setAttribute(PAGE_ERRORS_MESSAGES_KEY, errors);
	}

	@SuppressWarnings("unchecked")
	public void saveMessage(HttpServletRequest request, String msg) {
		List messages = (List) request.getSession().getAttribute(PAGE_SUCCESS_MESSAGES_KEY);
		if (messages == null) {
			messages = new ArrayList();
		}
		messages.add(msg);
		request.getSession().setAttribute(PAGE_SUCCESS_MESSAGES_KEY, messages);
	}
	
	/* (non-Javadoc)
	 * @see org.springframework.web.servlet.mvc.AbstractController#handleRequestInternal(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
	 */
	public ModelAndView handleRequest(HttpServletRequest request,HttpServletResponse response) throws Exception {
		//调用处理具体业务
		return processService(request,response);
	}

	/**
	 * 处理具体业务逻辑
	 * @param httpRequest javax.servlet.http.HttpServletRequest
	 * @param httpResponse javax.servlet.http.HttpServletResponse
	 * @throws Exception 异常
	 */
	protected ModelAndView processService(HttpServletRequest httpRequest,
								  HttpServletResponse httpResponse) throws Exception {
		this.andyRequest = new Request(httpRequest);
		this.setRequestParamer();
		ModelAndView modelAndView = new ModelAndView(this.getSuccessView());
		try{
			this.andyResponse = service.process(this.andyRequest);
			Map pageAttributes = this.andyResponse.getPageAttributes();
			modelAndView.addObject((this.andyResponse.isOk()? "success":"failure"), true);
			if( !pageAttributes.isEmpty() ){
				Iterator it = pageAttributes.keySet().iterator();
				while( it.hasNext() ){
					String key = (String)it.next();
					Object value = pageAttributes.get(key);
					//httpRequest.setAttribute(key, value);
					modelAndView.addObject(key, value);
				}
			}
			modelAndView.addObject(EXT_SUCCESS_KEY, andyResponse.isOk());
			modelAndView.addObject(EXT_MESSAGE_KEY,andyResponse.getResponseMessage());
			modelAndView.addObject(EXT_RESPONSE_CODE_KEY,andyResponse.getResponseCode());
			if( this.andyResponse.isOk() ){
				//将讲结果保存在request对象中和ModelAndView
				this.processResponse();
			}else{
				this.saveError(httpRequest, andyResponse.getResponseMessage());
				modelAndView.addObject(EXT_MESSAGE_KEY, andyResponse.getResponseMessage());
				modelAndView.addObject(EXT_EXCEPTION,StringUtil.getStackTrace(andyResponse.getStackTraceException()));
				if( this.failedView!=null && !"".equals(this.failedView)){
					modelAndView.setViewName(this.failedView);
				}
			}
		}catch(Exception ex){
			log.error("处理请求错误：",ex);
			this.saveError(httpRequest, "调用业务接口错误：" + ex.getMessage());
			modelAndView.addObject(EXT_MESSAGE_KEY, ex);
			httpRequest.setAttribute("exception", ex);
		}
		return modelAndView;
	}
	
	/**
	 * 子类可以定义覆盖此方法,设置调用的业务的请求参数
	 */
	protected abstract void setRequestParamer();
	
	/**
	 * 子类可以实现处理返回的结构，如把想要的对象写入到HttpServletRequest对象
	 */
	protected abstract void processResponse();
	
	/**
	 * @return the successView
	 */
	public String getSuccessView() {
		return successView;
	}

	/**
	 * @param successView the successView to set
	 */
	public void setSuccessView(String successView) {
		this.successView = successView;
	}

	/**
	 * @param service the service to set
	 */
	public void setService(IService service) {
		this.service = service;
	}

	/**
	 * @return the failedView
	 */
	public String getFailedView() {
		return failedView;
	}

	/**
	 * @param failedView the failedView to set
	 */
	public void setFailedView(String failedView) {
		this.failedView = failedView;
	}

}
